use rand::Rng;
use chrono::{DateTime, Utc};
use regex;
use reqwest;
use serde_json::Value;
use simd_json::serde;
use std::error::Error;
use std::time::Instant;
use crate::db::{models::{Canton, Goods, Notice, Target}, sqlite::{create_db, insert_notice, insert_or_update_canton, insert_or_update_goods, insert_or_update_target}};
use rusqlite;

/// 爬虫模块
/// 
/// 负责从济南交易网站获取土地交易数据，包括公告信息、交易信息和宗地信息，并将数据存入数据库。

/// 修复日期时间格式，将 "YYYY-MM-DDHH:MM:SS" 转换为 "YYYY-MM-DD HH:MM:SS"
/**
 * 修复日期时间格式
 * 
 * 将 "YYYY-MM-DDHH:MM:SS" 格式转换为标准的 "YYYY-MM-DD HH:MM:SS" 格式
 * 
 * @param text 需要修复的日期时间字符串
 * @return 修复后的标准格式日期时间字符串
 */
fn fix_datetime_format(text: &str) -> String {
    // 查找类似 YYYY-MM-DDHH:MM:SS 的模式并插入空格
    let re = regex::Regex::new(r"(\d{4}-\d{2}-\d{2})(\d{2}:\d{2}:\d{2})").unwrap();
    re.replace_all(text, "$1 $2").to_string()
}

/// 处理JSON，去除内部所有空格，并替换中文字符括号为英文括号
/**
 * 处理JSON字符串
 * 
 * 去除内部所有空格，并替换中文字符括号为英文括号，确保JSON能被正确解析
 * 
 * @param json_str 需要处理的JSON字符串
 * @return 处理后的标准JSON字符串
 */
fn process_json_string(json_str: &str) -> String {
    // 去除所有空格
    let no_spaces = json_str.replace(' ', "");
    
    // 替换中文字符括号为英文括号
    let mut result = String::with_capacity(no_spaces.len());
    for c in no_spaces.chars() {
        match c {
            '【' | '〔' => result.push('['),
            '】' | '〕' => result.push(']'),
            '｛' => result.push('{'),
            '｝' => result.push('}'),
            _ => result.push(c),
        }
    }
    result
}

/// 递归处理JSON值中的所有字符串
/**
 * 递归处理JSON值中的所有字符串
 * 
 * 对JSON对象中的所有字符串值应用process_json_string处理
 * 
 * @param value 需要处理的JSON值
 * @return 处理后的JSON值
 */
fn process_json_value(mut value: Value) -> Value {
    match &mut value {
        Value::Object(obj) => {
            for (_, v) in obj.iter_mut() {
                *v = process_json_value(std::mem::replace(v, Value::Null));
            }
        },
        Value::Array(arr) => {
            for v in arr.iter_mut() {
                *v = process_json_value(std::mem::replace(v, Value::Null));
            }
        },
        Value::String(s) => {
            *s = process_json_string(s);
        },
        _ => {},
    }
    value
}

/// 创建默认HTTP客户端
/**
 * 创建HTTP客户端
 * 
 * 创建一个默认的reqwest HTTP客户端
 * 
 * @return 成功时返回HTTP客户端，失败时返回错误
 */
fn create_client() -> Result<reqwest::Client, Box<dyn Error>> {
    reqwest::Client::builder().build().map_err(|e| e.into())
}

/**
 * 创建HTTP请求头
 * 
 * 创建标准的HTTP请求头，包括Content-Type和随机的User-Agent
 * 随机选择User-Agent以避免被目标网站识别为爬虫
 * 
 * @return 成功时返回请求头，失败时返回错误
 */
fn create_headers() -> Result<reqwest::header::HeaderMap, Box<dyn Error>> {
    let mut headers = reqwest::header::HeaderMap::new();
    headers.insert("Content-Type", "application/x-www-form-urlencoded".parse()?);

    // 常用浏览器User-Agent列表
    let user_agents = [
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_7_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Safari/605.1.15",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0",
        "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
        "Mozilla/5.0 (Linux; Android 14; SM-G998U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36",
        "Mozilla/5.0 (iPad; CPU OS 18_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.0",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_7_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
    ];

    // 随机选择一个User-Agent
    let random_user_agent = user_agents[rand::thread_rng().gen_range(0..user_agents.len())];
    headers.insert("User-Agent", random_user_agent.parse()?);

    Ok(headers)
}
/// 发送请求并获取解析后的JSON响应
/**
 * 发送请求并获取解析后的JSON响应
 * 
 * 发送POST请求到指定的API端点，获取响应并解析为JSON对象
 * 
 * @param client HTTP客户端
 * @param params 请求参数
 * @return 成功时返回解析后的JSON对象，失败时返回错误
 */
async fn fetch_json(
    client: &reqwest::Client,
    params: &std::collections::HashMap<&str, &str>,
) -> Result<Value, Box<dyn Error>> {
    let headers = create_headers()?;

    let response = client
        .post("http://119.164.252.44:8001/data")
        .headers(headers)
        .form(params)
        .send()
        .await?;

    let body = response.text().await?;
    // 修复日期时间格式
    let fixed_body = fix_datetime_format(&body);

    let mut json = fixed_body.as_bytes().to_vec();
    serde::from_slice(&mut json).map_err(|e| e.into())
}

/// 第一阶段，发送请求获取所有公告信息
/// 创建客户端，发送请求获取所有公告信息
/**
 * 获取济南交易网站的公告索引页数据
 * 
 * 发送请求获取指定页码和每页数量的公告列表
 * 
 * @param page_num 页码
 * @param page_size 每页数量
 * @return 成功时返回解析后的JSON对象，失败时返回错误
 */
async fn get_jn_jy_index(page_num: i64, page_size: i64) -> Result<Value, Box<dyn Error>> {
    // 创建HTTP客户端
    let client = reqwest::Client::new();

    // 设置请求参数并发送请求
    let page_num_str = page_num.to_string();
    let page_size_str = page_size.to_string();
    let mut params = std::collections::HashMap::new();
    params.insert("cantonId", "");        // 区县代码，空为全部
    params.insert("method", "targetOfNotice2");
    params.insert("service", "Query");
    params.insert("module", "portal");
    params.insert("targetStatus", "");     // 交易状态，空为全部
    params.insert("pageNum", &page_num_str); // 页码
    params.insert("pageSize", &page_size_str); // 每页数量
    
    let parsed: Value = fetch_json(&client, &params).await?;
    let parsed = process_json_value(parsed);
    Ok(parsed)
}

// 获取全部公告数据
/**
 * 获取所有页面的公告数据
 * 
 * 首先发送请求获取第一页数据，确定总页数，然后循环获取所有页面的公告数据
 * 处理每个页面的数据并将其存入数据库
 * 
 * @return 成功时返回Ok(()), 失败时返回错误
 */
pub async fn get_all_page() -> Result<(), Box<dyn Error>> {
    // 只创建一次数据库连接以提高性能
    let conn = create_db()?;

    // 记录开始时间用于性能分析
    let start_time = Instant::now();
    let start_datetime: DateTime<Utc> = Utc::now();
    println!("程序开始运行时间: {}", start_datetime.format("%Y-%m-%d %H:%M:%S"));
    
    // 首先获取区县信息
    println!("开始获取区县信息...");
    if let Err(e) = get_canton_info().await {
        println!("获取区县信息失败，但继续执行主任务: {:?}", e);
    }
    println!("区县信息获取完成");

    // 发送第一页请求获取公告信息
    let page_size = 50;
    let parsed_one: Value = get_jn_jy_index(1, page_size).await?;
    
    // 输出总记录数
    if let Some(total_row_count) = parsed_one["totalRowCount"].as_i64() {
        println!("totalRowCount: {}", total_row_count);
    }
    
    // 获取总页数
    let page_count = if let Some(count) = parsed_one["pageCount"].as_i64() {
        println!("pageCount: {}", count);
        count
    } else {
        1 // 默认只有一页
    };

    // 处理第一页数据
    process_notice_data(&conn, parsed_one).await;
    
    // 循环发送请求获取剩余页面数据
    for page_num in 2..=page_count {
        let parsed: Value = get_jn_jy_index(page_num, page_size).await?;
        process_notice_data(&conn, parsed).await;
    }

    // 记录并输出执行时间
    let end_time = Instant::now();
    let end_datetime: DateTime<Utc> = Utc::now();
    let duration = end_time.duration_since(start_time);
    
    println!("程序完成时间: {}", end_datetime.format("%Y-%m-%d %H:%M:%S"));
    println!("程序总运行时长: {}秒", duration.as_secs_f64());
    
    Ok(())
}

/**
 * 获取更新的公告数据
 * 
 * 实现增量更新逻辑：从第1页开始，每页获取30条公告
 * - 检查每条公告是否已存在于数据库
 * - 如果当前页的30条公告全部已存在，则退出函数（判定为已更新完成）
 * - 如果当前页存在未存储的公告，则继续获取下一页数据
 * 
 * @return 成功时返回Ok(()), 失败时返回错误
 */
pub async fn get_update_page() -> Result<(), Box<dyn Error>> {
    // 记录开始时间，用于性能监控和日志记录
    let start_time = Instant::now();
    let start_datetime: DateTime<Utc> = Utc::now();
    println!("更新程序开始运行时间: {}", start_datetime.format("%Y-%m-%d %H:%M:%S"));
    
    // 创建数据库连接，用于查询和存储公告数据
    println!("正在创建数据库连接...");
    let conn = create_db()?;
    println!("数据库连接创建成功");
    
    // 首先获取区县信息
    println!("开始获取区县信息...");
    if let Err(e) = get_canton_info().await {
        println!("获取区县信息失败，但继续执行主任务: {:?}", e);
    }
    println!("区县信息获取完成");
    
    // 核心参数设置：
    // - page_size: 每页获取的公告数量，固定为30
    // - page_num: 当前页码，从第1页开始
    // - has_new_data: 控制循环的标志位，判断是否继续获取下一页
    let page_size = 30;
    let mut page_num = 1;
    let mut has_new_data = true;
    println!("设置初始参数：page_size={}, page_num={}", page_size, page_num);
    
    // 主循环：只要当前页存在新数据，就继续获取下一页
    while has_new_data {
        println!("进入循环：正在获取第{}页数据，每页{}条", page_num, page_size);
        
        // 调用API获取指定页码和每页数量的公告列表数据
        println!("调用get_jn_jy_index获取页面数据...");
        let parsed: Value = match get_jn_jy_index(page_num, page_size).await {
            Ok(data) => {
                println!("成功获取到第{}页的数据", page_num);
                data
            },
            Err(e) => {
                println!("获取第{}页数据失败: {}", page_num, e);
                return Err(e);
            }
        };
        
        // 检查当前页数据是否包含新数据，并同时处理（存储或更新）这些数据
        println!("检查并处理第{}页数据...", page_num);
        let page_has_new_data = match check_and_process_update_page(&conn, parsed).await {
            Ok(has_new) => has_new,
            Err(e) => {
                println!("处理第{}页数据失败: {}", page_num, e);
                return Err(e);
            }
        };
        
        // 决策逻辑：
        // - 如果当前页没有新数据，说明前面的数据可能也没有新数据，可以停止更新
        // - 如果当前页有新数据，继续获取下一页
        if !page_has_new_data {
            println!("第{}页的所有公告已存在于数据库中，停止更新。", page_num);
            has_new_data = false; // 设置标志位为false，退出循环
        } else {
            println!("第{}页包含新数据，继续获取下一页。", page_num);
            page_num += 1; // 页码加1，准备获取下一页数据
            println!("准备获取第{}页数据", page_num);
        }
    }
    
    // 记录结束时间并计算总运行时长
    let end_time = Instant::now();
    let end_datetime: DateTime<Utc> = Utc::now();
    let duration = end_time.duration_since(start_time);
    
    // 输出运行结果信息
    println!("更新程序完成时间: {}", end_datetime.format("%Y-%m-%d %H:%M:%S"));
    println!("更新程序总运行时长: {}秒", duration.as_secs_f64());
    println!("总共处理了{}页数据", if page_num > 1 { page_num - 1 } else { page_num });
    
    Ok(())
}

/**
 * 检查并处理更新页面的数据
 * 
 * 核心功能：
 * 1. 遍历页面中的每条公告
 * 2. 检查公告是否已存在于数据库中
 * 3. 处理并存入/更新所有公告数据（无论是否新数据）
 * 4. 返回当前页面是否包含新数据的标志
 * 
 * @param conn 数据库连接，用于查询和更新操作
 * @param parsed 解析后的JSON数据，包含公告列表信息
 * @return 成功时返回bool值，表示是否包含新数据，失败时返回错误
 */
async fn check_and_process_update_page(conn: &rusqlite::Connection, parsed: Value) -> Result<bool, Box<dyn Error>> {
    // 初始化标志位，默认为false（假设没有新数据）
    let mut has_new_data = false;
    
    println!("开始处理页面数据...");
    
    // JSON数据解析和遍历逻辑：
    // 1. 检查顶层是否为对象
    println!("检查JSON数据格式...");
    if let Some(parsed_obj) = parsed.as_object() {
        println!("JSON是对象格式，查找notice_data字段...");
        if let Some(notice_data) = parsed_obj.get("notice_data") {
            println!("找到notice_data字段，检查是否为数组...");
            if let Value::Array(notice_array) = notice_data {
                println!("notice_data是数组格式，包含 {} 条公告记录", notice_array.len());
                
                // 遍历每条公告记录
                for (index, notice) in notice_array.iter().enumerate() {
                    println!("处理第 {} 条公告...", index + 1);
                    
                    // 获取公告ID，作为唯一标识
                    if let Some(notice_id) = notice["id"].as_str() {
                        println!("公告ID: {}", notice_id);
                        
                        // 查询数据库，检查该公告是否已存在
                        println!("检查公告是否已存在于数据库...");
                        let exists = match check_notice_exists(conn, notice_id) {
                            Ok(exists_flag) => {
                                println!("查询完成，公告{}数据库", if exists_flag { "已存在于" } else { "不存在于" });
                                exists_flag
                            },
                            Err(e) => {
                                println!("数据库查询失败: {}", e);
                                false // 出错时假设不存在，确保数据能被处理
                            }
                        };
                        
                        // 如果公告不存在，标记当前页面包含新数据
                        if !exists {
                            println!("发现新数据，设置has_new_data=true");
                            has_new_data = true;
                        }
                        
                        // 预处理阶段：从公告中提取必要信息
                        println!("提取公告必要信息...");
                        let mut notice_flag = true; // 控制公告处理逻辑的标志
                        let mut notice_date_cache = String::new(); // 存储公告日期
                        let mut area_cache = String::new(); // 存储区域信息
                        let mut identifier_cache = String::new(); // 存储标识符信息
                        
                        // 安全地提取各字段值，避免空指针
                        if let Some(notice_date) = notice["notice_date"].as_str() {
                            notice_date_cache = notice_date.to_string();
                            println!("公告日期: {}", notice_date_cache);
                        }
                        if let Some(area) = notice["area"].as_str() {
                            area_cache = area.to_string();
                            println!("区域信息: {}", area_cache);
                        }
                        if let Some(identifier) = notice["identifier"].as_str() {
                            identifier_cache = identifier.to_string();
                            println!("标识符: {}", identifier_cache);
                        }
                        
                        // 处理公告中的交易列表数据
                        println!("准备处理交易列表数据...");
                        if let Some(obj2) = notice.as_object() {
                            if let Some(list) = obj2.get("list") {
                                println!("找到交易列表，调用process_trade_list处理...");
                                // 调用专门的处理函数处理交易列表
                                process_trade_list(
                                    conn,
                                    list.clone(),
                                    &mut notice_flag,
                                    notice_id,
                                    &notice_date_cache,
                                    &area_cache,
                                    &identifier_cache
                                ).await;
                                println!("交易列表处理完成")
                            } else {
                                println!("当前公告没有交易列表数据");
                            }
                        } else {
                            println!("公告数据格式错误，无法提取交易列表");
                        }
                    } else {
                        println!("无法获取公告ID，跳过当前记录");
                    }
                    println!("第 {} 条公告处理完成\n", index + 1);
                }
            } else {
                println!("notice_data不是数组格式，跳过处理");
            }
        } else {
            println!("未找到notice_data字段，跳过处理");
        }
    } else {
        println!("JSON数据不是对象格式，跳过处理");
    }
    
    println!("页面数据处理完成，has_new_data = {}", has_new_data);
    // 返回当前页面是否包含新数据的标志
    Ok(has_new_data)
}

/**
 * 检查公告是否已存在于数据库中
 * 
 * 使用SQL查询检查特定公告ID是否已存在于notice_table表中
 * 采用SELECT 1的方式，仅判断是否存在，不返回具体数据，提高查询效率
 * 
 * @param conn 数据库连接，提供查询功能
 * @param notice_id 公告ID，作为查询的唯一条件
 * @return 成功时返回bool值，表示公告是否存在，失败时返回错误
 */
fn check_notice_exists(conn: &rusqlite::Connection, notice_id: &str) -> Result<bool, Box<dyn Error>> {
    // 准备SQL语句，使用参数化查询防止SQL注入
    let mut stmt = conn.prepare("SELECT 1 FROM notice_table WHERE notice_id = ?")?;
    
    // 执行exists查询，直接返回是否存在记录的布尔值
    // 当查询结果集为空时返回false，否则返回true
    let exists = stmt.exists([notice_id])?;
    
    Ok(exists)
}

/// 处理获取到的json公告数据
/**
 * 处理获取到的公告数据
 * 
 * 解析JSON中的公告信息，并调用process_trade_list处理每个公告中的交易列表
 * 
 * @param conn 数据库连接
 * @param parsed 解析后的JSON数据
 */
async fn process_notice_data(conn: &rusqlite::Connection, parsed: Value) {
    if let Some(parsed_obj) = parsed.as_object() {
        if let Some(notice_data) = parsed_obj.get("notice_data") {
            if let Value::Array(notice_array) = notice_data {
                // 循环遍历notice_data列表
                for notice in notice_array {
                    let mut notice_flag = true; // 用于从列表中获取一次公告名称
                    let mut notice_id_cache = String::new(); // 存储当前公告id
                    let mut notice_date_cache = String::new(); // 存储公告时间
                    let mut area_cache = String::new(); // 存储公告区县
                    let mut identifier_cache = String::new(); // 存储公告文号

                    if let Some(notice_id) = notice["id"].as_str() {
                        notice_id_cache = notice_id.to_string();
                    }
                    if let Some(notice_date) = notice["notice_date"].as_str() {
                        notice_date_cache = notice_date.to_string();
                    }
                    if let Some(area) = notice["area"].as_str() {
                        area_cache = area.to_string();
                    }
                    if let Some(identifier) = notice["identifier"].as_str() {
                        identifier_cache = identifier.to_string();
                    }
                    
                    // 处理公告中的交易列表
                    if let Some(obj2) = notice.as_object() {
                        if let Some(list) = obj2.get("list") {
                            // 克隆list以传递所有权给process_trade_list，并使用await等待异步函数完成
                            process_trade_list(
                                conn,
                                list.clone(), 
                                &mut notice_flag, 
                                &notice_id_cache,
                                &notice_date_cache,
                                &area_cache,
                                &identifier_cache
                            ).await;
                        }
                    }
                }
            }
        }
    }
}

/// 处理json公告信息中的交易列表
/**
 * 处理公告中的交易列表
 * 
 * 解析交易列表，避免重复交易，并为每个交易获取详细信息
 * 
 * @param conn 数据库连接
 * @param list 交易列表数据
 * @param notice_flag 公告标志，用于控制公告信息只插入一次
 * @param notice_id_cache 公告ID缓存
 * @param notice_date_cache 公告日期缓存
 * @param area_cache 公告区县缓存
 * @param identifier_cache 公告文号缓存
 */
async fn process_trade_list(conn: &rusqlite::Connection, list: Value, notice_flag: &mut bool, notice_id_cache: &str, notice_date_cache: &str, area_cache: &str, identifier_cache: &str) {
    // 存储交易编号，避开重复交易（多宗地合并出让）
    let mut trade_ids = std::collections::HashSet::new();
    
    if let Value::Array(ref list_array) = list {
        for trade in list_array {
            if let Some(target_id) = trade["target_id"].as_str() {
                // 跳过重复的交易ID
                if trade_ids.contains(target_id) {
                    continue;
                }
                
                // 只处理一次公告信息
                if *notice_flag {
                    if let Some(notice_name) = trade["notice_name"].as_str() {
                        *notice_flag = false;
                        
                        // 构建Notice对象，对notice_date应用日期时间格式修复
                        let notice = Notice {
                            notice_id: notice_id_cache.to_string(),
                            notice_date: fix_datetime_format(notice_date_cache),
                            area: area_cache.to_string(),
                            identifier: identifier_cache.to_string(),
                            notice_name: notice_name.to_string()
                        };
                        
                        // 将公告信息存入数据库
                        if let Err(e) = insert_notice(conn, &notice) {
                            println!("存储公告信息失败: {}", e);
                        }
                    }
                }

                // 将交易ID添加到集合中避免重复处理
                trade_ids.insert(target_id.to_string());

                // 根据target_id发送请求获取交易详情
                if let Err(e) = get_target(conn, target_id, notice_id_cache).await {
                    println!("获取交易详情失败: {}, target_id: {}", e, target_id);
                }
            }
        }
    }
}

/// 第二阶段、对每个交易分别发送请求
/// 详情页请求参数
/**
 * 创建交易详情请求参数
 * 
 * 创建查询交易详情所需的基础请求参数
 * 
 * @return 包含基础请求参数的HashMap
 */
fn create_target_params() -> std::collections::HashMap<&'static str, &'static str> {
    let mut params = std::collections::HashMap::new();
    params.insert("method", "queryTarget");
    params.insert("service", "Query");
    params.insert("module", "portal");
    params
}

/// 根据交易ID发送请求，获取交易详情的json数据
/**
 * 获取交易详情数据
 * 
 * 根据交易ID发送请求，获取交易详情的JSON数据
 * 
 * @param client HTTP客户端
 * @param target_id 交易ID
 * @return 成功时返回解析后的JSON对象，失败时返回错误
 */
async fn fetch_trade_detail(
    client: &reqwest::Client,
    target_id: &str,
) -> Result<Value, Box<dyn Error>> {
    let mut params = create_target_params();
    params.insert("targetId", target_id);
    
    // 使用fetch_json函数获取数据，它内部会修复日期时间格式
    let json = fetch_json(client, &params).await?;
    Ok(process_json_value(json))
}
/// 发送请求，获取交易信息和宗地信息
/// 对交易信息和宗地信息进行分析提取
/**
 * 获取交易信息和宗地信息
 * 
 * 发送请求获取交易详情，然后分别处理交易信息和宗地信息
 * 
 * @param conn 数据库连接
 * @param target_id 交易ID
 * @param notice_id_cache 公告ID缓存
 * @return 成功时返回Ok(()), 失败时返回错误
 */
async fn get_target(conn: &rusqlite::Connection, target_id: &str, notice_id_cache: &str) -> Result<(), Box<dyn Error>> {
    // 创建HTTP客户端
    let client = create_client()?;

    // 发送请求，获取json数据
    let parsed: Value = fetch_trade_detail(&client, target_id).await?;
    let mut parsed = process_json_value(parsed);

    if let Value::Object(ref mut obj) = parsed {
        // 分析交易信息
        if let Some(target) = obj.remove("target") {
            get_target_info(conn, target, notice_id_cache, target_id).await;
        }
        
        // 分析宗地信息
        if let Some(goods) = obj.remove("goods") {
            get_goods_info(conn, goods, target_id).await;
        } else {
            println!("宗地信息获取失败！target_id: {}", target_id);
        }
    }

    Ok(())
}

/// 解析交易信息
/**
 * 解析交易信息并存储到数据库
 * 
 * 从JSON数据中提取交易信息，构建Target对象，并将其插入或更新到数据库
 * 
 * @param conn 数据库连接
 * @param target 交易信息JSON数据
 * @param notice_id_cache 公告ID缓存
 * @param target_id 交易ID
 */
async fn get_target_info(conn: &rusqlite::Connection, target: Value, notice_id_cache: &str, target_id: &str) {
    // 构建Target对象，对所有日期时间字段应用格式修复
    let target_data = Target {
        target_id: target_id.to_string(),
        notice_id: notice_id_cache.to_string(),
        // 交易状态码: 5已成交，6流拍，4交易中/终止，7待审核，3已公告
        status: target["status"].as_i64().map(|v| v as i32),
        // 是否终止交易: 1终止交易，0未终止交易
        is_stop: target["is_stop"].as_i64().map(|v| v as i32),
        trans_bidder: target["trans_bidder"].as_str().map(|s| s.to_string()),
        end_trans_time: target["end_trans_time"].as_str().map(|s| fix_datetime_format(s)),
        trans_price: target["trans_price"].as_i64().map(|v| v as f32/10000.0),
        trans_price_above: target["trans_price_above"].as_i64().map(|v| v as f32),
        trans_price_under: target["trans_price_under"].as_i64().map(|v| v as f32),
        price_step: target["price_step"].as_i64().map(|v| v as f32/10000.0),
        begin_price: target["begin_price"].as_i64().map(|v| v as f32/10000.0),
        begin_price_above: target["begin_price_above"].as_i64().map(|v| v as f32),
        begin_price_under: target["begin_price_under"].as_i64().map(|v| v as f32),
        notice_xh: target["notice_xh"].as_str().map(|s| s.to_string()),
        begin_focus_time: target["begin_focus_time"].as_str().map(|s| fix_datetime_format(s)),
        end_focus_time: target["end_focus_time"].as_str().map(|s| fix_datetime_format(s)),
        begin_apply_time: target["begin_apply_time"].as_str().map(|s| fix_datetime_format(s)),
        end_apply_time: target["end_apply_time"].as_str().map(|s| fix_datetime_format(s)),
    };
    
    // 将交易信息存入数据库
    if let Err(e) = insert_or_update_target(conn, &target_data) {
        println!("交易信息存入数据库失败: {}, target_id: {}", e, target_id);
    }
}
/// 解析地块信息
/**
 * 解析宗地信息并存储到数据库
 * 
 * 从JSON数据中提取宗地信息，构建Goods对象，并将其插入或更新到数据库
 * 
 * @param conn 数据库连接
 * @param goods 宗地信息JSON数据
 * @param target_id 交易ID
 */
async fn get_goods_info(conn: &rusqlite::Connection, goods: Value, target_id: &str) {
    if let Value::Array(ref goods_array) = goods {
        for goods_item in goods_array {
            // 提取宗地基本信息
            let goods_id = goods_item["goods_id"].as_str().unwrap_or("").to_string();
            let business_name = goods_item["business_name"].as_str().map(|s| s.to_string());
            let goods_no = goods_item["goods_no"].as_str().map(|s| s.to_string());
            let goods_name = goods_item["goods_name"].as_str().map(|s| s.to_string());
            let land_area = goods_item["land_area"].as_str().map(|s| s.parse::<f32>().unwrap_or(0.0));
            let goods_use = goods_item["goods_use"].as_str().map(|s| s.to_string());
            let use_years = goods_item["use_years"].as_str().map(|s| s.to_string());
            let address = goods_item["address"].as_str().map(|s| s.to_string());
            
            // 提取价格信息
            let goods_begin_price = goods_item["goods_begin_price"].as_i64().map(|v| v as f32);
            let goods_begin_price_above = goods_item["goods_begin_price_above"].as_i64().map(|v| v as f32);
            let goods_begin_price_under = goods_item["goods_begin_price_under"].as_i64().map(|v| v as f32);
            let trans_goods_price = goods_item["trans_goods_price"].as_i64().map(|v| v as f32/10000.0);
            let trans_goods_price_above = goods_item["trans_goods_price_above"].as_i64().map(|v| v as f32);
            let trans_goods_price_under = goods_item["trans_goods_price_under"].as_i64().map(|v| v as f32);
            
            // 解析容积率信息
            let plot1_down = goods_item["plot1_down"].as_str().map(|s| s.to_string());
            let plot1_flag = goods_item["plot1_flag"].as_str().map(|s| s.to_string());
            let plot1_up = goods_item["plot1_up"].as_str().map(|s| s.to_string());
            let plot1_flag2 = goods_item["plot1_flag2"].as_str().map(|s| s.to_string());
            let plot2_down = goods_item["plot2_down"].as_str().map(|s| s.to_string());
            let plot2_flag = goods_item["plot2_flag"].as_str().map(|s| s.to_string());
            let plot2_up = goods_item["plot2_up"].as_str().map(|s| s.to_string());
            let plot2_flag2 = goods_item["plot2_flag2"].as_str().map(|s| s.to_string());
            
            // 建筑密度信息
            let build_density_down = goods_item["build_density_down"].as_str().map(|s| s.to_string());
            let build_density_flag = goods_item["build_density_flag"].as_str().map(|s| s.to_string());
            let build_density_up = goods_item["build_density_up"].as_str().map(|s| s.to_string());
            let build_density_flag2 = goods_item["build_density_flag2"].as_str().map(|s| s.to_string());
            
            // 建筑高度
            let ild_height = goods_item["build_height"].as_str().map(|s| s.to_string());
            
            // 绿地率信息
            let green_ratio_down = goods_item["green_ratio_down"].as_str().map(|s| s.to_string());
            let green_ratio_flag = goods_item["green_ratio_flag"].as_str().map(|s| s.to_string());
            let green_ratio_up = goods_item["green_ratio_up"].as_str().map(|s| s.to_string());
            let green_ratio_flag2 = goods_item["green_ratio_flag2"].as_str().map(|s| s.to_string());
            
            // 其他信息
            let remark = goods_item["remark"].as_str().map(|s| s.to_string());
            let other_condition = goods_item["otherCondition"].as_str().map(|s| s.to_string());
            let start_required = goods_item["startRequired"].as_str().map(|s| s.to_string());
            let deposit_price = goods_item["deposit_price"].as_str().map(|s| s.to_string());
            let price_step = goods_item["price_step"].as_i64().map(|v| v as f32/10000.0);
            let crj_yjk = goods_item["crj_yjk"].as_i64().map(|v| v as f32);
            let allow_union = goods_item["allow_union"].as_i64().map(|v| v as i32);
            let percent_price = goods_item["percent_price"].as_f64().map(|v| v as f32);
            let develop = goods_item["develop"].as_str().map(|s| s.to_string());
            
            // 构建Goods对象
              let goods = Goods {
                  goods_id: goods_id.clone(),
                  target_id: target_id.to_string(),
                  business_name,
                  goods_no,
                  goods_name,
                  land_area,
                  goods_use,
                  use_years,
                  address,
                  goods_begin_price,
                  goods_begin_price_above,
                  goods_begin_price_under,
                  trans_goods_price,
                  trans_goods_price_above,
                  trans_goods_price_under,
                  plot1_down,
                  plot1_flag,
                  plot1_up,
                  plot1_flag2,
                  plot2_down,
                  plot2_flag,
                  plot2_up,
                  plot2_flag2,
                  build_density_down,
                  build_density_flag,
                  build_density_up,
                  build_density_flag2,
                  ild_height,
                  green_ratio_down,
                  green_ratio_flag,
                  green_ratio_up,
                  green_ratio_flag2,
                  remark,
                  other_condition,
                  start_required,
                  deposit_price,
                  price_step,
                  crj_yjk,
                  allow_union,
                  percent_price,
                  develop,
              };
            
            // 存储goods信息到数据库
            if let Err(e) = insert_or_update_goods(conn, &goods) {
                println!("存储宗地信息失败: {}, goods_id: {}", e, goods_id);
            }
        }
    }
}

/// 获取区县信息并存储到数据库
/**
 * 发送请求获取区县信息，解析JSON响应，并将数据存入数据库
 * 
 * 发送POST请求到指定API，请求参数包括：
 * - module: portal
 * - service: Query
 * - method: queryCanton
 * 
 * @return 成功时返回Ok(()), 失败时返回错误
 */
pub async fn get_canton_info() -> Result<(), Box<dyn Error>> {
    println!("开始获取区县信息...");
    
    // 创建数据库连接
    let conn = create_db()?;
    println!("数据库连接创建成功");
    
    // 创建HTTP客户端
    let client = reqwest::Client::new();
    
    // 设置请求参数
    let mut params = std::collections::HashMap::new();
    params.insert("module", "portal");
    params.insert("service", "Query");
    params.insert("method", "queryCanton");
    
    println!("发送请求获取区县信息...");
    // 发送请求并获取JSON响应
    let parsed: Value = fetch_json(&client, &params).await?;
    let parsed = process_json_value(parsed);
    
    println!("开始解析区县数据...");
    
    // 打印完整的响应数据结构用于调试
    println!("完整响应: {:?}", parsed);
    
    // 解析JSON数据
    println!("完整响应数据类型: {}", if parsed.is_array() { "数组" } else if parsed.is_object() { "对象" } else { "其他" });
    
    // 尝试直接解析为数组
    if parsed.is_array() {
        println!("直接解析为数组，获取到 {} 条区县信息", parsed.as_array().unwrap().len());
        
        // 直接处理数组中的每个元素
        for item in parsed.as_array().unwrap() {
            process_canton_item(&conn, item).await?;
        }
    } else if parsed.is_object() {
        // 尝试多种可能的状态字段名
        let state = parsed["state"].as_i64().or_else(|| parsed["State"].as_i64()).or_else(|| parsed["STATUS"].as_i64());
        
        if let Some(state_value) = state {
            if state_value == 0 || state_value == 1 { // 接受0或1作为成功状态
                println!("获取区县信息成功，状态码: {}", state_value);
                
                // 尝试多种可能的数据字段名
                let canton_data = parsed.get("data").or_else(|| parsed.get("Data")).or_else(|| parsed.get("DATA"));
                
                if let Some(data) = canton_data {
                    println!("找到数据字段，数据类型: {:?}", data);
                    
                    // 根据数据格式进行处理
                    if let Value::Array(canton_array) = data {
                        println!("发现 {} 个区县数据", canton_array.len());
                        
                        // 遍历每个区县数据
                        for item in canton_array {
                            process_canton_item(&conn, &item).await?;
                        }
                    } else {
                        println!("区县数据格式不是数组，数据类型: {:?}", data);
                    }
                } else {
                    println!("响应中没有找到data字段，尝试检查对象中的其他字段");
                    
                    // 查看对象的所有字段
                    if let Some(map) = parsed.as_object() {
                        for (key, value) in map {
                            if value.is_array() {
                                println!("发现数组字段: {}, 长度: {}", key, value.as_array().unwrap().len());
                                // 尝试处理这个数组
                                for item in value.as_array().unwrap() {
                                    if item.is_object() {
                                        process_canton_item(&conn, &item).await?;
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                println!("获取区县信息失败，状态码: {}", state_value);
            }
        } else {
            println!("无法解析响应状态，检查是否有其他格式的响应");
            // 尝试直接访问可能的数据数组
            if let Value::Array(canton_array) = parsed {
                println!("响应本身是数组，发现 {} 个区县数据", canton_array.len());
                for item in canton_array {
                     process_canton_item(&conn, &item).await?;
                 }
            }
        }
    } else {
        println!("响应格式不符合预期: 既不是对象也不是数组");
    }
    
    println!("区县信息获取和存储完成");
    Ok(())
}

// 处理单个区县信息项的辅助函数
async fn process_canton_item(conn: &rusqlite::Connection, item: &Value) -> Result<(), Box<dyn Error>> {
    if item.is_object() {
        // 尝试从不同格式的字段中获取数据
        let canton_id = item["cantonId"].as_str()
            .or_else(|| item["CantonId"].as_str())
            .or_else(|| item["CANTONID"].as_str())
            .or_else(|| item["canton_id"].as_str())
            .unwrap_or("")
            .to_string();
        
        let canton_name = item["cantonName"].as_str()
            .or_else(|| item["CantonName"].as_str())
            .or_else(|| item["CANTONNAME"].as_str())
            .or_else(|| item["canton_name"].as_str())
            .map(|s| s.to_string());
        
        let organ_id = item["organId"].as_str()
            .or_else(|| item["OrganId"].as_str())
            .or_else(|| item["ORGANID"].as_str())
            .or_else(|| item["organ_id"].as_str())
            .map(|s| s.to_string());
        
        let orgen_name = item["organName"].as_str()
            .or_else(|| item["OrganName"].as_str())
            .or_else(|| item["ORGANNAME"].as_str())
            .or_else(|| item["orgen_name"].as_str())
            .or_else(|| item["organ_name"].as_str())
            .map(|s| s.to_string());
        
        println!("提取的数据 - canton_id: {}, canton_name: {:?}, organ_id: {:?}, orgen_name: {:?}", 
                 canton_id, canton_name, organ_id, orgen_name);
        
        // 只处理有效的区县数据
        if !canton_id.is_empty() {
            // 构建Canton对象
            let canton = Canton {
                id: None,
                canton_id: canton_id.clone(),
                canton_name,
                organ_id,
                orgen_name,
            };
            
            // 存储到数据库
            if let Err(e) = insert_or_update_canton(conn, &canton) {
                println!("存储区县信息失败: {}, canton_id: {}", e, canton.canton_id);
            } else {
                println!("成功存储区县信息: {}, {}", canton.canton_id, canton.canton_name.as_deref().unwrap_or("无名称"));
            }
        } else {
            println!("区县ID为空，跳过此条数据");
        }
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    // 使用tokio运行时来执行异步测试
    #[test]
    fn test_get_jn_jy_index() -> Result<(), Box<dyn Error>> {
        // 创建运行时执行异步函数
        let rt = tokio::runtime::Runtime::new()?;
        rt.block_on(get_update_page())
    }
}
